/*
 *  模型由多个部件组成,部件种类见 D3ModelPartType
 *  注意:
 *      1.右手坐标系,模型位于原点,前方x正方向,左边y正方向,头上z正方向
 *      2.输入模型坐标时,建议输入0~1范围的数值,再利用 width、height、thickness 来调整大小
 */
#ifndef _3D_MODEL_H_
#define _3D_MODEL_H_

#include <iostream>
#include "3d_unit.h"
#include "image_format.h"
#include "crosslist_base.h"

//部件类型
typedef enum {
    D3MODEL_PART_TYPE_LINE,     //空间直线
    D3MODEL_PART_TYPE_TRIANGLE, //空间三角平面
    D3MODEL_PART_TYPE_RECT,     //空间四边形(四个坐标需共面,否则中心区域深度计算不准)
} D3ModelPartType;

//模型部件
class D3ModelPart
{
public:
    D3ModelPartType type;

    //顶点
    float xyz[12] = {0};
    int32_t xyzNum = 4;

    //属性
    int32_t width = 1, height = 1, thickness = 1; //宽(y轴)、高(z轴)、厚(x轴)
    uint32_t color = 0; //纯色填充
    Film *film = NULL; //图片填充,自动拉伸,用于 D3MODEL_PART_TYPE_RECT 部件

    D3ModelPart(float *xyz, D3ModelPartType type, uint32_t color = 0, Film *film = NULL);
    void Print();
};

//模型由多个线条、三角平面、四边平面组成
class D3Model
{
public:
    CrossList *partsList = NULL;

    D3Model();
    ~D3Model();

    //模型顶点构建,返回在 partsList 子链表中的序号, -1失败
    int32_t AddLine(float xyz[6], uint32_t color = 0);
    int32_t AddLine(float x1, float y1, float z1,
                float x2, float y2, float z2,
                uint32_t color = 0);

    int32_t AddTriangle(float xyz[9], uint32_t color = 0);
    int32_t AddTriangle(float x1, float y1, float z1,
                    float x2, float y2, float z2,
                    float x3, float y3, float z3,
                    uint32_t color = 0);

    int32_t AddRect(float xyz[12], uint32_t color = 0, Film *film = NULL);
    int32_t AddRect(float x1, float y1, float z1,
                float x2, float y2, float z2,
                float x3, float y3, float z3,
                float x4, float y4, float z4,
                uint32_t color = 0, Film *film = NULL);

    //返回指定序号的部件
    D3ModelPart *PartAt(int32_t index);
    int32_t PartNum();
    int32_t SetPartColor(int32_t index, uint32_t color);
    int32_t SetPartFilm(int32_t index, Film *film);

    //整体缩放,取值范围: 0.0 ~ 缩放区间 ~ 1.0 ~ 放大区间 ~ XXX
    //在模型构建完毕后使用,否则后续添加进来的 part 未参与缩放
    void Zoom(float multiple);
};

#endif // _3D_MODEL_H_
